package com.buba.utils;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @projectName: TwoProject
 * @package: com.buba.project.utils
 * @className: RedisConfig
 * @author: Eric
 * @description: Redis配置类，更换key的默认序列化器
 * @date: 2022/8/9 11:16
 * @version: 1.0
 */
@Configuration  //告诉Spring Boot这是一个配置类 == 配置文件
public class RedisConfig {
//通过配置RedisConfig类继承CachingConfigurerSupport，将Spring-Cache的缓存换为Redis。
//    public class RedisConfig extends CachingConfigurerSupport {

    @Bean      //给容器中添加组件，以方法名作为组件的id。返回类型为组件类型，返回的值，就是组件在容器中的实例
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { //覆盖框架默认的缓存
        // 创建 RedisTemplate 对象
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);
        //使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化) / 初始化连接池
        Jackson2JsonRedisSerializer<Object> s = new Jackson2JsonRedisSerializer<Object>(Object.class);
        // 创建ObjectMapper对象  ObjectMapper从JSON属性匹配到Java属性的过程
        ObjectMapper objectMapper = new ObjectMapper();
        /*
        * 不是所有的字段都支持序列化和反序列化，需要符合以下规则：
            如果想更改默认的序列化和反序列化规则，需要调用 ObjectMapper 的 setVisibility() 方法。
            * 否则将会抛出 InvalidDefinitionException 异常。
        * */
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
        s.setObjectMapper(objectMapper);
        StringRedisSerializer ss = new StringRedisSerializer();
        redisTemplate.setDefaultSerializer(s);
        // 设置 Key 的序列化 - String 序列化 RedisSerializer.string() => StringRedisSerializer.UTF_8
        redisTemplate.setKeySerializer(ss);//StringRedisSerializer 对需要缓存的对象进行序列化操作！！！！
        redisTemplate.setHashKeySerializer(ss);
        // 设置 Value 的序列化 - String 序列化 RedisSerializer.string() => StringRedisSerializer.UTF_8
        redisTemplate.setValueSerializer(s);
        redisTemplate.setHashValueSerializer(s);
        //afterPropertiesSet方法，初始化bean的时候执行，可以针对某个具体的bean进行配置。
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean      //给容器中添加组件，以方法名作为组件的id。返回类型为组件类型，返回的值，就是组件在容器中的实例
    public RedisTemplate<Object, Object> redisTemplates(RedisConnectionFactory connectionFactory) { //覆盖框架默认的缓存
        // 创建 RedisTemplate 对象
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);
        StringRedisSerializer ss = new StringRedisSerializer();
        redisTemplate.setKeySerializer(ss);//StringRedisSerializer 对需要缓存的对象进行序列化操作！！！！
        redisTemplate.setHashKeySerializer(ss);
        // 设置 Value 的序列化 - String 序列化 RedisSerializer.string() => StringRedisSerializer.UTF_8
        redisTemplate.setValueSerializer(ss);
        redisTemplate.setHashValueSerializer(ss);
        //afterPropertiesSet方法，初始化bean的时候执行，可以针对某个具体的bean进行配置。
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }


}
